<template>
  <div style="height:100%;" class="haloe-menu-outer" :style="styles">

    <div class="haloe-menu-header" v-if="header && mode==='vertical' && !modelValue">
      {{ header }}
    </div>

    <ul :class="classes" :style="ulStyles" >
      <slot></slot>
    </ul>
    <!-- </template> -->

    <slot name="trigger">
      <div
        v-show="collapsible && mode==='vertical'"
        :class="triggerClasses"
        :style="triggerStyle"
        @click="toggleCollapse"
      >
        <i :class="triggerIconClasses"></i>
      </div>
    </slot>
    <!-- <div
      v-if="this.scalable || this.scalaDown"
      class="right-hand"
      style="display:inline-block;width:10px;height:60px;background-color: #fff;position:absolute;
box-shadow: 0px 2px 10px 0px rgba(153,153,153,0.5);
border-radius: 0px 2px 2px 0px;"
      :style="iconStyles">
      <e-icon v-if="!this.scalaDown" type="caret-right1" color="#999" @click="handleScalaUp" style="text-align:center;margin-top:22px;"/>
      <e-icon v-if="this.scalaDown" type="caret-left1" color="#999"  @click="handleScalaDown" style="text-align:center;margin-top:22px;"/>
    </div> -->
  </div>
</template>
<script>
import { nextTick, VueElement } from 'vue'
import { oneOf, findComponentsUpward } from '../../utils/assist'
import collapseTransition from '../base/collapse-transition.vue'
const prefixCls = 'haloe-menu'

export default {
  name: 'Menu',
  emits: ['on-select', 'on-open-change','scala-up','scala-down','update:modelValue'],
  // components:{collapseTransition},
  provide() {
    return {
      MenuInstance: this,
    }
  },
  props: {
    mode: {
      validator(value) {
        return oneOf(value, ['horizontal', 'vertical'])
      },
      default: 'vertical',
    },
    theme: {
      validator(value) {
        return oneOf(value, ['light', 'dark', 'primary'])
      },
      default: 'light',
    },
    activeName: {
      type: [String, Number, Object],
    },
    openNames: {
      type: Array,
      default() {
        return []
      },
    },
    accordion: {
      type: Boolean,
      default: false,
    },
    width: {
      type: String,
      default: '240px',
    },
    scalable:{
      type: Boolean,
      default: false,
    },
    scalaDown:{
      type: Boolean,
      default: false,
    },
    scalableIconTop: {
      type: String,
      default: null,
    },
    scalableIconRight: {
      type: String,
      default: null,
    },
    scalableIconLeft: {
      type: String,
      default: null,
    },
    scalableIconButton: {
      type: String,
      default: null,
    },
    modelValue: { // 双向绑定, true表示收起, false表示展开
      type: Boolean,
      default: false
    },
    collapsible: { // 是否可展开收起
      type: Boolean,
      default: false
    },
    triggerTop: {
      type: [ String, Number ],
    },
    header: {
      type: String,
      default: null,
    }
    // collapsedWidth: { // 合并后宽度
    //   type: [Number, String],
    //   default: 64
    // },
    // hideTrigger: { // 是否隐藏触发器
    //   type: Boolean,
    //   default: false
    // },
    // defaultCollapsed: { // 默认是否合并
    //   type: Boolean,
    //   default: false
    // }
  },
  data() {
    return {
      currentActiveName: this.activeName,
      openedNames: [],
      submenuList: [],
      menuItemList: [],
      ready: false,
      current: this.modelValue,
    }
  },
  computed: {
    classes() {
      let theme = this.theme
      if (this.mode === 'vertical' && this.theme === 'primary') theme = 'light'
      return [
        `${prefixCls}`,
        `${prefixCls}-${theme}`,
        {
          [`${prefixCls}-${this.mode}`]: this.mode,
          [`${prefixCls}-collapse`]: this.mode === 'vertical' && this.modelValue
        },
      ]
    },

    styles() {
      let style = {}
      // if (this.mode === 'vertical') style.width = this.width
      if (this.mode === 'vertical') {
        // let width=this.collapsible ? (this.modelValue ? parseInt(this.collapsedWidth) : parseInt(this.width)) : parseInt(this.width);
        let width = this.collapsible ? (this.modelValue ? 50 : parseInt(this.width)) : parseInt(this.width);
        style={
          width: width+'px',
          // flex:`0 0 ${width}px`,
          height: '100%'
        }
      }
      return style
    },

    ulStyles() {
      let style = {}
      if (this.mode === 'vertical') {
        let width = this.collapsible ? (this.modelValue ? 50 : parseInt(this.width)) : parseInt(this.width);
        let height = '100%'
        if (!this.modelValue && this.header) {
          height = 'calc(100% - 60px)'
        }
        style = {
          width: width + 'px',
          height
        }
      }
      return style
    },

    triggerStyle(){
      let style = {};
      if(this.triggerTop) {
        style.top = parseInt(this.triggerTop) + 'px'
      }
      return style
    },

    iconStyles() {
      let style = {}
      if(this.scalable || this.scalaDown) {
        style.top = this.scalableIconTop
        style.left = this.scalableIconLeft
        style.right = this.scalableIconRight
        style.bottom = this.scalableIconButton
      }
      return style
    },

    // showMeun(){
    //   return this.collapsible &&!this.modelValue;
    // },

    triggerClasses(){
      return [
        `${prefixCls}-trigger`,
        this.modelValue ? `${prefixCls}-trigger-collapsed` : '',
      ];
    },

    triggerIconClasses(){
      return [
        'haloe-menu-icon',
        `${prefixCls}-trigger-icon`,
      ];
    },
  },

  methods: {
    updateActiveName() {
      if (this.currentActiveName === undefined) {
        this.currentActiveName = -1
      }

      this.submenuList
        .map((item) => item.submenu)
        .forEach((item) => {
          item.handleUpdateActiveName(false)
        })

      this.menuItemList
        .map((item) => item.menuitem)
        .forEach((item) => {
          item.handleUpdateActiveName(this.currentActiveName)
        })
    },

    updateOpenKeys(name) {
      let names = [...this.openedNames]
      const index = names.indexOf(name)
      const submenuList = this.submenuList.map((item) => item.submenu)
      if (this.accordion)
        submenuList.forEach((item) => {
          item.opened = false
        })
      if (index >= 0) {
        let currentSubmenu = null
        submenuList.forEach((item) => {
          if (item.name === name) {
            currentSubmenu = item
            item.opened = false
          }
        })
        findComponentsUpward(currentSubmenu, 'Submenu').forEach((item) => {
          item.opened = true
        })
        currentSubmenu.childSubmenuList
          .map((item) => item.submenu)
          .forEach((item) => {
            item.opened = false
          })
      } else {
        if (this.accordion) {
          let currentSubmenu = null
          submenuList.forEach((item) => {
            if (item.name === name) {
              currentSubmenu = item
              item.opened = true
            }
          })
          findComponentsUpward(currentSubmenu, 'Submenu').forEach((item) => {
            item.opened = true
          })
        } else {
          const submenuList = this.submenuList.map((item) => item.submenu)
          submenuList.forEach((item) => {
            if (item.name === name) item.opened = true
          })
        }
      }
      let openedNames = submenuList
        .filter((item) => item.opened)
        .map((item) => item.name)
      this.openedNames = [...openedNames]
      this.$emit('on-open-change', openedNames)
    },

    updateOpened() {
      const items = (this.submenuList || []).map((item) => item.submenu)
      if (items.length) {
        items.forEach((item) => {
          if (this.openedNames.indexOf(item.name) > -1) item.opened = true
          else item.opened = false
        })
      }
    },

    handleEmitSelectEvent(name) {
      this.$emit('on-select', name)
    },

    handleMenuItemSelect(name) {
      this.currentActiveName = name
      this.$emit('on-select', name)
    },

    handleScalaUp(e) {
      this.$emit('scala-up')
    },

    handleScalaDown(e) {
      this.$emit('scala-down')
    },

    /**
   * 导航切换展开收起
   */
    toggleCollapse () {
      let value = this.collapsible ? !this.modelValue : false;
      this.current = value
      this.$emit('update:modelValue', value);
    }

  },
  mounted() {
    this.openedNames = [...this.openNames]
    this.updateOpened()
    nextTick(() => {
      this.updateActiveName()
      this.ready = true
    })
  },
  watch: {
    openNames(names) {
      this.openedNames = names
    },
    activeName(val) {
      this.currentActiveName = val
    },
    currentActiveName() {
      this.updateActiveName()
    },
    current(modelValue){
      // console.log('2222222222modelValue', modelValue)
    }
  },
}
</script>
